uefi 安装启动

·

Secure Boot 的签名链(PK/KEK/DB) 中的各自的作用?

结合完整的 Secure Boot 启动链(shim → grub → kernel) 进行详细的解释

信任链的根源 (OEM/固件)

  • 首先,UEFI 安全启动的信任链始于固件(BIOS/UEFI)。固件中预先存储了三个关键的密钥数据库:

  • 平台密钥 (PK - Platform Key): 最高级的密钥,用于签署 KEK 的更新。由 PC 制造商 (OEM) 负责管理。

  • 密钥交换密钥 (KEK - Key Exchange Key): 用于签署签名数据库 (db) 和禁止签名数据库 (dbx) 的更新。

  • 签名数据库 (db - Signature Database): 包含了被允许执行的操作系统引导加载程序、驱动程序等组件的公钥或证书。

  • 初始状态下,这个 db 数据库中通常包含:

  • OEM 自己的证书: 用于验证固件更新和 OEM 自己的工具。

  • Microsoft Corporation UEFI CA 证书: 允许启动所有由微软签名的组件,包括 Windows 启动管理器以及由微软服务签名的第三方引导加载程序。

UEFI 固件内部存有四类关键数据库:

名称类型主要作用由谁管理
PK(Platform Key)公开证书 + 私钥在厂商手上管理平台最顶层权限(用来更新 KEK)OEM(华硕、联想等)
KEK(Key Exchange Key)公开证书用来更新 DB / DBXOEM、Microsoft
DB(Allowed Signatures)允许列表证书 + Hash允许启动的 EFI 程序的签名Microsoft(多数 PC),OEM,用户
DBX(Forbidden Signatures)禁止列表证书 + Hash被吊销/恶意的 EFI 程序摘要Microsoft

Secure Boot 的工作原则:UEFI 只允许 DB 中签名的文件启动,禁止 DBX 中的文件。

  1. UEFI 会从 DB/DBX 中取证书来验证 shim 的签名
  2. shim.efi 验证 grubx64.efi(第二级验证)
    • shim 内置了一个 shim-own certificate (MOK)
      • → 是从 Linux 发行版(或用户)生成的
      • → 不需要微软参与
    • 所以 shim 的验证过程:
      • shim 内的 MOK 列表(Machine Owner Keys) ↓ 验证 grub 是否被 MOK 签名 grub 才能启动
    • shim 的最大用途:让 Linux 自己管理信任链,而不依赖微软。
    • 用户也可以加入自己的 MOK(mokutil --import)这样用户可以签:
      • grub
      • kernel
      • initrd
      • 甚至自己写的 EFI 程序
  3. grubx64.efi 验证 Linux kernel(第三级验证)
    • 使用 shim 提供的验证接口(shim_lock)
      • ↓ 验证 kernel 是否被 MOK(DB)签名
      • kernel 才能加载
  4. 通常:
    • 在 Ubuntu / Debian,kernel 已经用 Canonical 的私钥签名(内置在 shim MOK 内)
    • 在 Fedora,kernel 用 Red Hat 的私钥签名
    • 所以 grub加载内核时会调用 shim 的验证函数:
    • verify_pe_signature()
    • 决定内核是否可信。

微软的角色:商业公司的“代理签名”

  • 微软确实在为其他商业公司签名方面扮演了核心角色,但不是直接负责。
  • 机制: 微软提供了一个 UEFI CA (Certificate Authority) 证书,这个证书被全球几乎所有 OEM 预装在了 UEFI 固件的 db 数据库中。
  • 服务: 许多第三方操作系统供应商或硬件/驱动程序制造商(如主流的 Linux 发行版,如 Canonical/Ubuntu、Red Hat 等)为了让他们的启动文件能在一台开启了安全启动的 Windows 电脑上运行,会向微软的 硬件仪表板(Hardware Dashboard) 提交他们的启动文件(例如 Linux 的 shim.efi)。
  • 签名: 微软使用自己的 Microsoft UEFI CA 证书的私钥,为这些第三方文件进行数字签名。
  • 结果: 固件检查启动文件时,发现它是由 Microsoft UEFI CA 签名的,而这个 CA 证书在 db 数据库中是被信任的,因此允许启动。

自己签名 Secure Boot 的实际流程(完整步骤)

下面是 Linux 下常见的方式(OpenSSL + sbsigntools):

① 生成三套密钥(PK/KEK/DB)

openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout PK.key -out PK.crt -subj "/CN=Custom PK/" -days 3650
openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout KEK.key -out KEK.crt -subj "/CN=Custom KEK/" -days 3650
openssl req -new -x509 -newkey rsa:2048 -sha256 -keyout DB.key -out DB.crt -subj "/CN=Custom DB/" -days 3650

② 生成 UEFI 可识别的 .auth 文件

cert-to-efi-sig-list -g "$(uuidgen)" PK.crt PK.esl
sign-efi-sig-list -k PK.key -c PK.crt PK PK.esl PK.auth

KEK/DB 同理。

③ 进入 BIOS,切换到 Custom Secure Boot

大多数设备 BIOS 中选择:
Secure Boot → Custom Mode
然后可以导入你的 PK.auth, KEK.auth, DB.auth

④ 使用你的 DB 私钥签名引导程序

例如对 GRUB2 EFI 文件签名:
sbsign --key DB.key --cert DB.crt --output grubx64.efi grubx64.efi
然后用这个签名过的 grubx64.efi 启动即可。